﻿/*
 * LabelRenderer
 * 
 * initial implementation : 20.10.2008
 *
 * Copyright (c) Adam Sida, asida@centrum.cz.
 * All rights reserved.
 * 
 * for license see Petra.Gis.License.txt
 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using Petra.Gis.Geometry;
using Petra.Gis.Geometry.Support;
using Petra.Gis.DataServices;
using Petra.Gis.RenderingServices.PlanarBase;
using Petra.Gis.ReferenceSystemServices.Transformations;

namespace Petra.Gis.RenderingServices.GDIPlus
{


  /// <summary>
  /// renders point as 'dot' in map of defined size and color
  /// </summary>
  public partial class LabelRenderer : BitmapMapRendererBase
  {

    //protected Pen _outpen;
    protected Font _outFont;
    protected SolidBrush _outBrush;


    //public LabelRenderer(BitmapMap map, RenderStyle s)
    //  :base(map, s){ }





    public override void PrepareToRender()
    {
      base.PrepareToRender();

      //string t1 = (string)_style["FontFamilyName"];
      //float f1 = System.Convert.ToSingle(_style["FontSize"]);
      //FontStyle fff = (FontStyle)_style["FontStyle"];
      //GraphicsUnit gg = (GraphicsUnit)_style["GraphicsUnit"];

      _outFont = new Font(((string)renderStyle["FontFamilyName"]),
                          System.Convert.ToSingle(renderStyle["FontSize"]),
                          (FontStyle)renderStyle["FontStyle"],
                          (GraphicsUnit)renderStyle["GraphicsUnit"]);

      _outBrush = new SolidBrush((Color)renderStyle["FontColor"]);

    }




    /// <summary>
    /// method that implements drawing (conversion) of gis geometry into output format geometry
    /// </summary>
    /// <param name="geometry">any system type currently</param>
    public override void RenderGeometry(GeometryBase geometry)
    {
      renderGeometry(_forwardTransform.Transform(geometry));
    }






    protected void renderGeometry(GeometryBase geometry)
    {
      //validate type against supported types
      if (geometry is Label)
        renderLabel((Label)geometry);

      else if (geometry is MultiLabel)
        foreach (Label p in (MultiLabel)geometry)
          renderLabel(p);

      else if (geometry is GeometryCollection)
        foreach (GeometryBase g in (GeometryCollection)geometry)
          renderGeometry(g);
    }




    protected virtual void renderLabel(Label lb)
    {
      //todo:add rotation, snappoint,...
      System.Drawing.Point p = ((DisplayTransformMatrix)((BitmapMap)rendererMap).RenderTransform).ProjectionToMap(lb.X, lb.Y);





      // if point falls into visible map area then draw
      if (getPointIntesectMask(p) == 0)
      {

        SizeF s = _outGraphic.MeasureString(lb.Text, _outFont);

        switch (lb.TextAlignment)
        {
          case Label.TextAlignmentType.BottomLeft:
            break;
          case Label.TextAlignmentType.CenterCenter:
            {
              p.X += (int)s.Width / 2;
              p.Y -= (int)s.Height / 2;
            }
            break;
          default:
            throw new NotImplementedException();
        }

        _outGraphic.TranslateTransform(p.X, p.Y);
        _outGraphic.RotateTransform((float)lb.Rotation, MatrixOrder.Append);

        _outGraphic.DrawString(lb.Text, _outFont, _outBrush, p.X, p.Y);

        _outGraphic.ResetTransform();

      }
    }




    public override DomainGeometryTypeEnum RendererGeometryDomain
    {
      get { return DomainGeometryTypeEnum.Label; }
    }




    public override bool IsRenderable(GeometryBase geometry)
    {
      if (geometry is Label)
        return true;
      else
        return false;
    }




  }
}
